#include <iostream>
#include <cstdlib>
#include <ctime>

using namespace std;

    // 定义雷区大小
    const int rols = 10;
    const int cols = 10;
    // 定义雷的数量
    const int NUM_MINES = 20;

    /**
     * @param gameBoard 界面数组界面
     * @param mineBoard 地雷数组界面
    */

// 初始化数组
void initialise(char gameBoard[rols][cols], char mineBoard[rols][cols])
{
    for (int i = 0; i < rols; i++)
    {
        for (int j = 0; j < cols; j++)
        {
         
            gameBoard[i][j] = '*'; 
        
            mineBoard[i][j] = '0'; 
        }
    }
}

// 布雷
void arrange(char mineBoard[rols][cols])
{
    srand(time(NULL));
    int minesPlaced = 0;
    while (minesPlaced < NUM_MINES)
    {
        int row = rand() % rols;
        int col = rand() % cols;
        if (mineBoard[row][col] == '0')
        {
            mineBoard[row][col] = '#';
            minesPlaced++;                 
        }
    }
}

// 计算某个位置周围的雷的数量
int number_mine(char mineBoard[rols][cols], int row, int col)
{
    int count = 0;
    for (int i = row - 1; i <= row + 1; i++)
    {
        for (int j = col - 1; j <= col + 1; j++)  
        {
            if (i >= 0 && i < rols && j >= 0 && j < cols && mineBoard[i][j] == '#')
            {
                count++;
            }
        }
    }
    return count;
}
// 打印游戏界面
void printBoard(char board[rols][cols])
{
    for (int i = 0; i < rols; i++)
    {
        for (int j = 0; j < cols; j++)
        {
            std::cout << board[i][j] << " ";
        }
        std::cout << std::endl;
    }
}


void expand_blank_area(char gameBoard[][cols],
                       char mineBoard[][cols],
                       int row,
                       int col)
{
    // 递归函数首先完成终止条件，而且有时候终止条件需要分开完成。
    // 1. 【终止条件】下标越界
    if (rols < 0 || rols > row - 1 || cols < 0 || cols > col - 1)
    {
        return;
    }

    // 2. 【终止条件】当前用户界面已经进行了展开限制，不再是 '*'
    if (gameBoard[rols][cols] != '*')
    {
        return;
    }

    // 3. 【终止条件】真实雷区中，对应下标位置已经不是 0， 需要终止展开，同时将对应
    // 真实雷区数据赋值给当前的用户界面
    if (mineBoard[rols][cols] >= '1' && mineBoard[rols][cols] <= '8')
    {
        gameBoard[rols][cols] = mineBoard[rols][cols];
        return;
    }

    if ('0' == mineBoard[rols][cols])
    {
        /*
        其他情况下。当前真实雷区的数据一定的是字符 0 ，直接进行赋值到用户界面操作，同时
        开启【递归模式】进行展开操作
        */
        gameBoard[rols][cols] = '_';

        expand_blank_area(gameBoard, mineBoard, row, col - 1);
        expand_blank_area(gameBoard, mineBoard, row, col + 1);

        expand_blank_area(gameBoard, mineBoard, row + 1, col - 1);
        expand_blank_area(gameBoard, mineBoard, row + 1, col);
        expand_blank_area(gameBoard, mineBoard, row + 1, col + 1);

        expand_blank_area(gameBoard, mineBoard, row - 1, col - 1);
        expand_blank_area(gameBoard, mineBoard, row - 1, col);
        expand_blank_area(gameBoard, mineBoard, row - 1, col + 1);
    }
}

// 探索操作
void explore(char gameBoard[rols][cols], char mineBoard[rols][cols], int row, int col)
{
    if (mineBoard[row][col] == '#')
    {
        std::cout << "Game Over$$$$$$" << std::endl
                  << "Game Over$$$$$$" << std::endl
                  << "Game Over$$$$$$" << std::endl
                  << "Game Over$$$$$$" << std::endl;
        return;
    }
       
   
  

    expand_blank_area(gameBoard, mineBoard, row, col);
    

    printBoard(gameBoard);

}

// 标记雷区
void mark_Mine(char gameBoard[rols][cols], int row, int col)
{
    if (gameBoard[row][col] == '*')
    {
        gameBoard[row][col] = 'F';
    } 
}

// 取消标记
void unmark_Mine(char gameBoard[rols][cols], int row, int col)
{
    if (gameBoard[row][col] == 'F')
    {
        gameBoard[row][col] = '*';
    }
}


int main()
{
    char gameBoard[rols][cols];
    char mineBoard[rols][cols];
    initialise(gameBoard, mineBoard);
    arrange(mineBoard);

    int markedCount = 0;
    int correct_Marked_Count = 0;

    while (true)
    {
        std::cout << "游戏开始: " << std::endl;

        printBoard(mineBoard);
        std::cout << std::endl;

        printBoard(gameBoard);

        std::cout <<"输入行，列 和动作(e: 探索, f: 标记, u: 取消标记): ";
        std::cout << std::endl;

        

        int row, col;
        char action;
        std::cin >> row >> col >> action;
        if (row < 0 || row >= rols || col < 0 || col >= cols)
        {
            std::cout << "输入的行或列超出范围，请重新输入" << std::endl;
            continue;
        }

        if (action == 'e')
        {
            explore(gameBoard, mineBoard, row, col);

        }

        else if (action == 'f')
        {
            mark_Mine(gameBoard, row, col);
            markedCount++;
            if (mineBoard[row][col] == '*')
            {
                correct_Marked_Count++;
            }
        }

        else if (action == 'u')
        {
            unmark_Mine(gameBoard, row, col);
            markedCount--;
        }
        if(correct_Marked_Count == NUM_MINES && markedCount == NUM_MINES)
        {
            std::cout << "You Win！！！！！" << std::endl 
                      << "You Win！！！！！" << std::endl
                      << "You Win！！！！！" << std::endl;
            break;
        }
    }
    return 0;
}